package com.mall.server.service.ums;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mall.autoconfig.exception.BusinessException;
import com.mall.common.util.JwtUtils;
import com.mall.dubbo.api.UmsAdminApi;
import com.mall.dubbo.api.UmsMenuApi;
import com.mall.dubbo.api.UmsRoleApi;
import com.mall.model.domain.UmsAdmin;
import com.mall.model.domain.UmsMenu;
import com.mall.model.domain.UmsRole;
import com.mall.model.vo.AdminInfoVo;
import com.mall.model.vo.CommonPage;
import com.mall.server.interceptor.UserHolder;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.mall.common.util.Constants.TOKEN_HEAD;

/**
 * @author : xyiaao
 * @createDate : 2022/3/30 12:27
 */
@Service
public class UmsAdminService {

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @DubboReference
    private UmsAdminApi umsAdminApi;

    @DubboReference
    private UmsRoleApi umsRoleApi;


    @DubboReference
    private UmsMenuApi umsMenuApi;


    @Autowired
    private Redisson redisson;


    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;


    public Map login(String username, String password) {

        UmsAdmin user = umsAdminApi.findUmsAdmin(username, password);
        if (user == null) {
            throw new BusinessException("无此用户！");
        }
        if (!bCryptPasswordEncoder.matches(password, user.getPassword())) {
            throw new BusinessException("密码错误！");
        }
        if (user.getStatus() == 0) {
            throw new BusinessException("该账户已被禁用");
        }
        user.setLoginTime(new Date());
        umsAdminApi.updateById(user);
        return getTokenMap(user.getId());
    }

    public Map getTokenMap(Long id) {
        // 通过JWT生成token
        Map tokenMap = new HashMap();
        tokenMap.put("id", id);
        String token = JwtUtils.getToken(tokenMap);
        // 构造返回值
        Map retMap = new HashMap();
        retMap.put("token", token);
        retMap.put("tokenHead", TOKEN_HEAD);
        return retMap;
    }

    public AdminInfoVo info() {
        // 根据用户id获取用户信息
        UmsAdmin umsAdmin = umsAdminApi.findUmsAdminById(UserHolder.getId());
        // 根据用户id获取对应角色信息
        UmsRole umsRole = umsRoleApi.findUmsRoleByUmsAdminId(umsAdmin.getId());
        // 根据角色id获取菜单列表
        List<UmsMenu> umsMenuList = umsMenuApi.listUmsMenuByRoleId(umsRole.getId());
        return AdminInfoVo.init(umsAdmin, umsRole, umsMenuList);
    }

    public void delete(Long id) {

        umsAdminApi.delete(id);
    }

    public CommonPage<UmsAdmin> list(String keyword, Integer pageNum, Integer pageSize) {

        Page<UmsAdmin> pageInfo = umsAdminApi.listPage(keyword, pageNum, pageSize);
        return new CommonPage<>(pageInfo);
    }

    public UmsAdmin register(UmsAdmin umsAdmin) {

        RLock lock = redisson.getLock(umsAdmin.getUsername());
        try {
            lock.lock(60, TimeUnit.SECONDS);
            if (umsAdminApi.findUmsAdminByUsername(umsAdmin.getUsername()) == null) {
                umsAdmin.setPassword(bCryptPasswordEncoder.encode(umsAdmin.getPassword()));
                return umsAdminApi.register(umsAdmin);
            }
            throw new BusinessException("该用户名已被使用");
        } finally {
            lock.unlock();
        }
    }

    public void roleUpdate(Integer adminId, List<Integer> roleIds) {

        umsAdminApi.roleUpdate(adminId, roleIds);
    }

    public List<UmsRole> roleAdminId(Integer adminId) {

        UmsRole umsRole = umsAdminApi.findRoleByAdminId(adminId);
        ArrayList<UmsRole> umsRoles = new ArrayList<>();
        umsRoles.add(umsRole);
        return umsRoles;
    }

    public void update(UmsAdmin umsAdmin) {

        if (StringUtils.isNotEmpty(umsAdmin.getPassword())) {
            umsAdmin.setPassword(bCryptPasswordEncoder.encode(umsAdmin.getPassword()));
        }
        umsAdminApi.updateById(umsAdmin);
    }

    public void updatePassword(String username, String newPassword) {

        UmsAdmin umsAdmin = umsAdminApi.findUmsAdminByUsername(username);
        if (umsAdmin != null) {
            umsAdmin.setPassword(newPassword);
            umsAdminApi.updateById(umsAdmin);
        }
        throw new BusinessException("无此用户");
    }

    public void updateStatus(Integer id, Integer status) {

        UmsAdmin umsAdmin = umsAdminApi.getById(id);
        umsAdmin.setStatus(status);
        umsAdminApi.updateById(umsAdmin);
    }

    public UmsAdmin getUmsAdmin(Integer id) {

        return umsAdminApi.getById(id);
    }

}
